package com.googlecode.skald.client.ui;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

import com.google.gwt.user.client.ui.Anchor;
import com.googlecode.skald.client.affordances.MenuOption;
import com.googlecode.skald.client.cmds.AffordanceCommand;

/**
 * Maps anchor widgets displayed in the GUI to their corresponding
 * {@link GameObject}.  A registry has a single style of menu and affordance
 * commands that it applies to all of its registered objects.  
 * <p>
 * A GameObject's state is usually valid only for the duration of a single 
 * server response.  Once the player selects an action and the game server 
 * responds again, all old GameObjects should be discarded.  Call the 
 * {@link #clear()} method to do this.
 * 
 * @author Zach Tomaszewski
 */
public class GameObjectRegistry {
  
  private Map<String, GameObject> reg = new HashMap<String, GameObject>();
  private EnumSet<MenuOption> opts;
  private AffordanceCommand builder;
  
  /**
   * Builds a new registry.  All object added to this registry will be
   * given the same menu options and will use the same AffordanceCommand type,
   * as specified here.  (If you need more than one such style or behavior
   * of in-text anchors at different points in the UI, use duplicate 
   * registries.)
   */
  public GameObjectRegistry(EnumSet<MenuOption> opts, 
                            AffordanceCommand builder) {
    this.opts = opts;
    this.builder = builder;
  }
  
  /**
   * Associates the the given anchor with the given object in this registry.  
   * Creates a new GameObject entry if the registry does not yet contain 
   * objName; otherwise, registers this tag as another duplicate anchor for 
   * an existing object.
   */
  public void add(String objName, Anchor a) {
    if (reg.containsKey(objName)) {
      reg.get(objName).add(a);
    }else {
      GameObject obj = new GameObject(objName, opts, builder);
      obj.add(a);
      reg.put(objName, obj);
    }
  }
  
  public void clear() {
    for (GameObject gobj : this.reg.values()) {
      gobj.disable();
    }
    this.reg.clear();
  }
  
}
